/*
 * TazioNetwork.java    0.0.1    27/dic/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */
package org.mentalsmash.tazio.transparency.interfaces;

import java.io.Serializable;

import org.mentalsmash.tazio.commons.identifiers.NID;

/**
 * This interface has the role of masking the underlying components used to send
 * messages and to provide the upper layers with methods to send messages to
 * WeakReplicaManagers and to ReplicaManagers connected to the group and to
 * register as a listener for incoming {@link TazioMessage}s.
 * <p>
 * The reason for adding this indirection level was taken in order to uniform
 * the way of accessing three different components such as the
 * {@link Dispatcher}, the {@link Point2PointCommunication} and the
 * {@link GroupConnection}, this way the upper layers will only have to access
 * this object, instead of keeping references to three different objects.
 * </p>
 * 
 * @version 0.0.1 27/dic/2009
 * @author Enrico Savioli <savioli.enrico@gmail.com>
 */
public interface TazioNetwork {

    public static final String HOST_OID = "host-oid";

    /**
     * This method is invoked by a ReplicaManager to send a message to the
     * WeakReplicaManager identified by the {@link TazioNodeID} NID provided as
     * an input parameter.
     * 
     * @param <T>
     *            a class implementing {@link Serializable}, which is the type
     *            of the message that will be sent to the WeakReplicaManager.
     * @param message
     *            the object of type T which will be sent to the
     *            WeakReplicaManager.
     * @param NID
     *            the {@link TazioNodeID} identifying the recipient of the
     *            message.
     * @return the {@link TazioMessage} which has been returned as an answer to
     *         the sent message.
     * 
     */
    <T extends Serializable> Serializable send(T message, NID nid);

    /**
     * This method is used to send a Serializable object, or a subclass of it,
     * to the group.
     * <p>
     * This method will have to encapsulate the message into a
     * {@link TazioMessage} object in order to grant the uniformity of messages
     * delivered throughout the system.
     * </p>
     * <p>
     * The object is sent with an asynchronous behavior, thus it will not block
     * in order to wait for answers to the message.
     * </p>
     * 
     * @param <T>
     *            an object implementing the {@link Serializable} interface.
     * @param message
     *            the Serializable object that has to be encapsulated into a
     *            {@link TazioMessage} and sent to other ReplicaManagers in the
     *            group.
     */
    <T extends Serializable> void sendToGroup(T message);

    /**
     * This method has to be invoked by a component interested in a specific
     * type of message.
     * <p>
     * The {@link InputMessageListener} passed as a parameter will be added to
     * the list of listeners for the specified message type.
     * </p>
     * 
     * @param <T>
     *            a subclass of {@link Serializable}.
     * @param msgClass
     *            the type of message the listener is interested into.
     * @param listener
     *            the {@link InputMessageListener listener} that will be
     *            notified when a message of the specified type is received.
     */
    void register(Class<? extends Serializable> msgClass,
	    InputMessageListener listener);

    /**
     * This method has to be invoked by a component that wants to be removed
     * from the listeners of a message.
     * <p>
     * The {@link InputMessageListener} passed as a parameter will be removed
     * from the list of listeners for the specified message type.
     * </p>
     * 
     * 
     * @param <T>
     *            a subclass of {@link Serializable}.
     * @param msgClass
     *            the type of message the listener is no more interested into.
     * @param listener
     *            the {@link InputMessageListener listener} that will be removed
     *            from the list of objects interested in messages of the
     *            specified type.
     */
    void unregister(Class<? extends Serializable> msgClass,
	    InputMessageListener listener);

    /**
     * This method is used to retrieve an array containing the
     * {@link TazioNodeID}s of all the WeakReplicaManagers connected to this
     * ReplicaManager.
     * 
     * @return the {@link TazioNodeID}s of all the WRMs connected to the RM.
     */
    NID[] getWeakReplicaManagers();

}
